package physicalobjects;

import forces.Force;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import simulationhandlers.Simulation;



/**
 * This class is a spring.
 *
 * @author Robert C. Duvall
 */
public class Spring implements PhysicalObject {
    private Mass myStart;
    private Mass myEnd;
    private double myLength;
    private double myK;
    private final double myWhiteColorThreshold = 0.001;

    /**
     *
     * @param start 
     * @param end 
     * @param length 
     * @param kVal 
     */
    public Spring (Mass start, Mass end, double length, double kVal) {
        myStart = start;
        myEnd = end;
        myLength = length;
        myK = kVal;
    }

    @Override
    public void paint (Graphics2D pen) {
        int xStart = (int) myStart.getCenter().getX();
        int yStart = (int) myStart.getCenter().getY();
        int xEnd = (int) myEnd.getCenter().getX();
        int yEnd = (int) myEnd.getCenter().getY();
        double dx = xStart - xEnd;
        double dy = yStart - yEnd;
        double len = Math.sqrt(dx * dx + dy * dy) - myLength;

        if (Math.abs(len) < myWhiteColorThreshold) {
            pen.setColor(Color.WHITE);
        }
        else if (len < 0.0) {
            pen.setColor(Color.BLUE);
        }
        else {
            pen.setColor(Color.RED);
        }
        pen.drawLine(xStart, yStart, xEnd, yEnd);
    }

    @Override
    public void update (Simulation canvas, double dt) {
        double[] dxdyPair = getChange(myStart, myEnd);
        // apply hooke's law to each attached mass
        Force f = new Force(Force.angleBetween(dxdyPair[0], dxdyPair[1]), myK *
                (myLength - Force.distanceBetween(dxdyPair[0], dxdyPair[1])));
        applyForce(f);
    }
    /**
     * 
     * @param startMass 
     * @param endMass 
     * @return
     */
    public double[] getChange(Mass startMass, Mass endMass) {
        Point2D start = startMass.getCenter();
        Point2D end = endMass.getCenter();
        double dx = start.getX() - end.getX();
        double dy = start.getY() - end.getY();
        double[] dxdyPair = new double[2];
        dxdyPair[0] = dx;
        dxdyPair[1] = dy;
        return dxdyPair;
    }
    /**
     * 
     * 
     * @param f 
     */
    public void applyForce(Force f) {
        myStart.applyForce(f);
        f.negate();
        myEnd.applyForce(f);
    }
}
